﻿using System;
using System.Collections.Generic;
using System.Web;
using OSGeo.MapGuide;
using System.Collections.Specialized;
using System.Collections;
using System.Xml;
using System.IO;
using System.Configuration;
using NegevGas;
using System.Reflection;
using System.Diagnostics;
namespace NegevGas.Extensions.markup
{
    public class MarkupManager : utilityfunctions
    {
        string libraryPath = ConfigurationManager.AppSettings["MarkupLibraryPath"].ToString();

        //public const String LL84WKT = "LOCAL_CS[\"*XY-MT*\",LOCAL_DATUM[\"*X-Y*\",10000],UNIT[\"Meter\", 1],AXIS[\"X\",EAST],AXIS[\"Y\",NORTH]]";
        public const string LL84WKT = "PROJCS[\"Israel.IsraeliGrid\",GEOGCS[\"Israel.LL\",DATUM[\"Israel\",SPHEROID[\"GRS1980\",6378137.000,298.25722210],TOWGS84[-48.0000,55.0000,52.0000,0.000000,0.000000,0.000000,0.00000000]],PRIMEM[\"Greenwich\",0],UNIT[\"Degree\",0.017453292519943295]],PROJECTION[\"Transverse_Mercator\"],PARAMETER[\"false_easting\",219529.584],PARAMETER[\"false_northing\",626907.390],PARAMETER[\"scale_factor\",1.000006700000],PARAMETER[\"central_meridian\",35.20451694444445],PARAMETER[\"latitude_of_origin\",31.73439361111111],UNIT[\"Meter\",1.00000000000000]]";
        NameValueCollection args = null;
        private MgSiteConnection site = null;
        public static bool IsDebugAssembly(Assembly assm)
        {

            foreach (object attr in assm.GetCustomAttributes(false))
            {

                if (attr is DebuggableAttribute)
                {

                    return ((DebuggableAttribute)attr).IsJITTrackingEnabled;

                }

            }

            return false;

        }
        public  MarkupManager(NameValueCollection incomingArgs)
        {
            try
            {
                /*if (IsDebugAssembly(this.GetType().Assembly))
                        System.Diagnostics.Debugger.Launch();*/
            this.args = incomingArgs;
            this.site = new MgSiteConnection();
           
            this.site.Open(new MgUserInformation(GetParameter(this.args, "SESSION")));
            if (!string.IsNullOrEmpty(GetParameter(this.args, "DIR")))
                libraryPath = GetParameter(this.args, "DIR");

            else
            {
                MgResourceService resourceService = (MgResourceService)this.site.CreateService(MgServiceType.ResourceService);

                MgMap map = new MgMap();
                map.Open(resourceService, GetParameter(this.args, "MAPNAME"));
                string path = map.MapDefinition.Path;
                if (path.ToLower().EndsWith("maps")) path = path.Substring(0, path.Length - 4);
                //Debug  
                
                 
            //    libraryPath = Path.Combine(String.Format("Library://{0}", path), "Markup/");
             //   libraryPath = "Library://" + path + "Markup/";
              //  Response.Write(libraryPath);
            }
            }
            catch (System.Exception ex)
            {
                throw ex;
             //   Response.Write("\n MarkupManager manager" + ex.InnerException);

            }
           
        }

        public Hashtable GetAvailableMarkup()
        {
            Hashtable markup = new Hashtable();

            MgResourceService resourceService = (MgResourceService)this.site.CreateService(MgServiceType.ResourceService);
            MgResourceIdentifier resourceID = new MgResourceIdentifier(libraryPath);

            try
            {
                MgByteReader byteReader = resourceService.EnumerateResources(resourceID, 1, "LayerDefinition");
                String resourceListXML = byteReader.ToString();

                XmlDocument doc = new XmlDocument();
                doc.LoadXml(resourceListXML);
                XmlNodeList nodeList = doc.GetElementsByTagName("ResourceId");

                foreach (XmlElement element in nodeList)
                {
                    MgResourceIdentifier resourceId = new MgResourceIdentifier(element.InnerText);
                    markup[resourceId.ToString()] = resourceId.GetName();
                }
            }
            catch (MgResourceNotFoundException mge)
            {
                // If the Library://Markup folder does not exist, create it.
                resourceService.SetResource(resourceID, null, null);
            }

            return markup;
        }

        public void OpenMarkup()
        {

            MgResourceService resourceService = (MgResourceService)this.site.CreateService(MgServiceType.ResourceService);

            MgMap map = new MgMap();
            map.Open(resourceService, GetParameter(this.args, "MAPNAME"));

            // Create the Layer Groups

            MgLayerGroup markupGroup = null;
            MgLayerGroupCollection layerGroups = map.GetLayerGroups();
            if (layerGroups.Contains("_Markup"))
            {
                markupGroup = layerGroups.GetItem("_Markup");
            }
            else
            {
                markupGroup = new MgLayerGroup("_Markup");
                markupGroup.SetVisible(true);
                markupGroup.SetLegendLabel("Markup");
                markupGroup.SetDisplayInLegend(false);
                layerGroups.Add(markupGroup);
            }

            // Add the Markup Layer

            MgResourceIdentifier markupLayerResId = new MgResourceIdentifier(GetParameter(this.args, "MARKUPLAYER"));
            MgLayer markupLayer = new MgLayer(markupLayerResId, resourceService);
            markupLayer.SetName("_" + markupLayerResId.GetName());
            markupLayer.SetLegendLabel(markupLayerResId.GetName());
            markupLayer.SetDisplayInLegend(false);
            markupLayer.SetSelectable(true);
            markupLayer.SetGroup(markupGroup);
            map.GetLayers().Insert(0, markupLayer);

            map.Save(resourceService);
        }

        public void CloseMarkup()
        {
            MgResourceService resourceService = (MgResourceService)this.site.CreateService(MgServiceType.ResourceService);

            MgMap map = new MgMap();
            map.Open(resourceService, GetParameter(this.args, "MAPNAME"));

            // Add the Markup Layer

            MgResourceIdentifier markupLayerResId = new MgResourceIdentifier(GetParameter(this.args, "OPENMARKUP"));
            int index = map.GetLayers().IndexOf("_" + markupLayerResId.GetName());
            map.GetLayers().RemoveAt(index);

            map.Save(resourceService);
        }

        public void CreateMarkup(string mgSessionId,string  mgMap)
        {
            //Response.Write("CreateMarkup" );
            MgUserInformation userInfo = new MgUserInformation(mgSessionId);
            MgSiteConnection siteConnection = new MgSiteConnection();
            siteConnection.Open(userInfo);

            MgResourceService resourceService = (MgResourceService)siteConnection.CreateService(MgServiceType.ResourceService);
            MgFeatureService featureService = (MgFeatureService)siteConnection.CreateService(MgServiceType.FeatureService);

           


          

            MgMap map = new MgMap();
            map.Open(resourceService, mgMap);
        //    map.Open(resourceService, GetParameter(args, "MAPNAME"));

            // Create the Markup Feature Source (SDF)

            MgResourceIdentifier markupSdfResId = new MgResourceIdentifier(libraryPath + GetParameter(this.args, "MARKUPNAME") + ".FeatureSource");

            MgFeatureSchema markupSchema = MarkupSchemaFactory.CreateMarkupSchema();
            MgCreateSdfParams sdfParams = new MgCreateSdfParams("XY-M", map.MapSRS, markupSchema);
            featureService.CreateFeatureSource(markupSdfResId, sdfParams);

            String url = "concat(&apos;" + GetParameter(this.args, "MARKUPURL") + "&apos;, concat(&apos;?key=&apos;, &quot;ID&quot;))";
            //Link to ProjectManager
          /*  if (GetParameter(this.args, "LINKTOPROJECTMANAGER").ToLower() == "on"
                && !String.IsNullOrEmpty(GetParameter(this.args, "ProjectCollectionName"))
                && GetParameter(this.args, "ProjectCollectionName") != "áçø îøùéîä")
            {
                string projectCollectionName = GetParameter(this.args, "ProjectCollectionName");
                if (projectCollectionName == "àçø...")
                {
                    projectCollectionName = GetParameter(this.args, "ProjectCollectionOtherName");
                }
                int projectId = 0;
                using (var conn = new System.Data.SqlClient.SqlConnection(ConfigurationManager.ConnectionStrings["ProjectManagerConnectionString"].ConnectionString))
                {
                    var cmd = conn.CreateCommand();
                    cmd.CommandText = "INSERT INTO ProjectCollections(LayoutId, FeatureId, ProjectCollectionName) VALUES(@LayoutId, @FeatureId, @ProjectCollectionName); SELECT @@IDENTITY AS [NEWID]";
                    cmd.CommandType = System.Data.CommandType.Text;

                    var layoutIdParam = new System.Data.SqlClient.SqlParameter("@LayoutId", System.Data.SqlDbType.NVarChar, 255);
                    layoutIdParam.Value = GetParameter(args, "LAYOUT");
                    cmd.Parameters.Add(layoutIdParam);

                    var featureIdParam = new System.Data.SqlClient.SqlParameter("@FeatureId", System.Data.SqlDbType.NVarChar, 255);
                    featureIdParam.Value = markupSdfResId.ToString();
                    cmd.Parameters.Add(featureIdParam);

                    var pcNameParam = new System.Data.SqlClient.SqlParameter("@ProjectCollectionName", System.Data.SqlDbType.NVarChar, 50);
                    pcNameParam.Value = projectCollectionName;
                    cmd.Parameters.Add(pcNameParam);

                    conn.Open();
                    //projectId = (int)cmd.ExecuteScalar();
                    using (var reader = cmd.ExecuteReader())
                    {
                        if (reader.Read())
                        {
                            projectId = Convert.ToInt32(reader[0]);
                        }
                    }
                }
                string host = HttpContext.Current.Request.Url.Host;
                url = String.Format("concat('http://{0}/MgExtensions/ProjectManager/default.aspx?ProjectId={1}&UID=', \"UID\")", host, projectId);
            }
            */
            // Create the Markup Layer Definition

            String hexFgTransparency = String.Format("{0:X2}", 255 * (100 - Int32.Parse(GetParameter(this.args, "FILLTRANSPARENCY"))) / 100); // Convert % to an alpha value
            String hexBgTransparency = GetParameter(this.args, "FILLBACKTRANS").Length > 0 ? "FF" : "00";							 // All or nothing
            String bold = GetParameter(this.args, "LABELBOLD").Length > 0 ? "true" : "false";
            String italic = GetParameter(this.args, "LABELITALIC").Length > 0 ? "true" : "false";
            String underline = GetParameter(this.args, "LABELUNDERLINE").Length > 0 ? "true" : "false";

            String markupLayerDefinition = File.ReadAllText(HttpContext.Current.Request.ServerVariables["APPL_PHYSICAL_PATH"] + "Extensions\\markup\\templates\\markuplayerdefinition.xml");
            markupLayerDefinition = String.Format(markupLayerDefinition,
                markupSdfResId.ToString(),						                //<ResourceId> - Feature Source
                GetParameter(this.args, "LABELSIZEUNITS"),						//<Unit> - Mark Label
                GetParameter(this.args, "LABELFONTSIZE"),						//<SizeX> - Mark Label Size
                GetParameter(this.args, "LABELFONTSIZE"),						//<SizeY> - Mark Label Size
                "FF" + GetParameter(this.args, "LABELFORECOLOR"),				//<ForegroundColor> - Mark Label
                "FF" + GetParameter(this.args, "LABELBACKCOLOR"),				//<BackgroundColor> - Mark Label
                GetParameter(this.args, "LABELBACKSTYLE"),						//<BackgroundStyle> - Mark Label
                bold,												            //<Bold> - Mark Label
                italic,											                //<Bold> - Mark Label
                underline,											            //<Underlined> - Mark Label
                GetParameter(this.args, "MARKERSIZEUNITS"),						//<Unit> - Mark
                GetParameter(this.args, "MARKERSIZE"),							//<SizeX> - Mark
                GetParameter(this.args, "MARKERSIZE"),							//<SizeY> - Mark
                GetParameter(this.args, "MARKERTYPE"),							//<Shape> - Mark
                "FF" + GetParameter(this.args, "MARKERCOLOR"),					//<ForegroundColor> - Mark
                "FF" + GetParameter(this.args, "MARKERCOLOR"),					//<Color> - Mark
                GetParameter(this.args, "LABELSIZEUNITS"),						//<Unit> - Line Label
                GetParameter(this.args, "LABELFONTSIZE"),						//<SizeX> - Line Label Size
                GetParameter(this.args, "LABELFONTSIZE"),						//<SizeY> - Line Label Size
                "FF" + GetParameter(this.args, "LABELFORECOLOR"),				//<ForegroundColor> - Line Label
                "FF" + GetParameter(this.args, "LABELBACKCOLOR"),				//<BackgroundColor> - Line Label
                GetParameter(this.args, "LABELBACKSTYLE"),						//<BackgroundStyle> - Line Label
                bold,												            //<Bold> - Line Label
                italic,											                //<Bold> - Line Label
                underline,											            //<Underlined> - Line Label			
                GetParameter(this.args, "LINEPATTERN"),							//<LineStyle> - Line
                GetParameter(this.args, "LINETHICKNESS"),						//<Thickness> - Line
                "FF" + GetParameter(this.args, "LINECOLOR"),					//<Color> - Line
                GetParameter(this.args, "LINESIZEUNITS"),						//<Unit> - Line
                GetParameter(this.args, "LABELSIZEUNITS"),						//<Unit> - Polygon Label
                GetParameter(this.args, "LABELFONTSIZE"),						//<SizeX> - Polygon Label Size
                GetParameter(this.args, "LABELFONTSIZE"),						//<SizeY> - Polygon Label Size
                "FF" + GetParameter(this.args, "LABELFORECOLOR"),				//<ForegroundColor> - Polygon Label
                "FF" + GetParameter(this.args, "LABELBACKCOLOR"),				//<BackgroundColor> - Polygon Label
                GetParameter(this.args, "LABELBACKSTYLE"),						//<BackgroundStyle> - Polygon Label
                bold,												            //<Bold> - Polygon Label
                italic,											                //<Bold> - Polygon Label
                underline,											            //<Underlined> - Polygon Label
                GetParameter(this.args, "FILLPATTERN"), 						//<FillPattern> - Fill
                hexFgTransparency + GetParameter(this.args, "FILLFORECOLOR"), 	//<ForegroundColor> - Fill
                hexBgTransparency + GetParameter(this.args, "FILLBACKCOLOR"), 	//<BackgroundColor> - Fill
                GetParameter(this.args, "BORDERPATTERN"),						//<LineStyle> - Fill
                GetParameter(this.args, "BORDERTHICKNESS"), 					//<Thickness> - Fill
                "FF" + GetParameter(this.args, "BORDERCOLOR"), 					//<Color> - Fill
                GetParameter(this.args, "BORDERSIZEUNITS"), 					//<Unit> - Fill
                HttpContext.Current.Server.HtmlEncode(url)); //<Url> - url link

            MgByteReader byteReader = new MgByteReader(markupLayerDefinition, "text/xml");
            resourceService.SetResource(new MgResourceIdentifier(libraryPath + GetParameter(this.args, "MARKUPNAME") + ".LayerDefinition"), byteReader, null);
        }

        public bool DeleteMarkup()
        {
            bool result = false;

            MgResourceService resourceService = (MgResourceService)this.site.CreateService(MgServiceType.ResourceService);
            MgFeatureService featureService = (MgFeatureService)this.site.CreateService(MgServiceType.FeatureService);

            MgResourceIdentifier markupLayerResId = new MgResourceIdentifier(GetParameter(args, "MARKUPLAYER"));
            MgResourceIdentifier markupSdfResId = new MgResourceIdentifier(libraryPath + markupLayerResId.GetName() + ".FeatureSource");

            //Check related entries in maintenance
            MgMap map = new MgMap();
            map.Open(resourceService, GetParameter(this.args, "MAPNAME"));

           /* string path = map.MapDefinition.Path;
            if (path.ToLower().EndsWith("maps")) path = path.Substring(0, path.Length - 4);
            path = Path.Combine(String.Format("Library://{0}", path), "Maintenance/Data/Maintenance.FeatureSource");

            MgResourceIdentifier maintenanceResId = new MgResourceIdentifier(path);

            MgLayer layer = new MgLayer(markupLayerResId, resourceService);
            if (!map.GetLayers().Contains(layer))
            {
                if (resourceService.ResourceExists(maintenanceResId))
                {
                    MgFeatureQueryOptions opt = new MgFeatureQueryOptions();
                    opt.SetFilter(String.Format("FeatureSource='{0}'", markupSdfResId.ToString()));

                    MgFeatureReader reader = featureService.SelectFeatures(maintenanceResId, "Maintenance:Maintenance", opt);
                    if (!reader.ReadNext())
                    {
                        resourceService.DeleteResource(markupLayerResId);
                        resourceService.DeleteResource(markupSdfResId);
                        result = true;
                    }
                }
                else
                {*/
                    resourceService.DeleteResource(markupLayerResId);
                    resourceService.DeleteResource(markupSdfResId);
                    result = true;
            /*    }
            }*/

            //================================================

            return result;
        }

        public Hashtable GetOpenMarkup()
        {
            Hashtable openMarkup = new Hashtable();

            MgResourceService resourceService = (MgResourceService)this.site.CreateService(MgServiceType.ResourceService);

            MgMap map = new MgMap();
            map.Open(resourceService, GetParameter(this.args, "MAPNAME"));

            MgLayerGroupCollection layerGroups = map.GetLayerGroups();
            if (layerGroups.Contains("_Markup"))
            {
                MgLayerCollection layers = map.GetLayers();

                for (int i = 0; i < layers.GetCount(); i++)
                {
                    MgLayer layer = (MgLayer)layers.GetItem(i);
                    if ((layer.GetGroup() != null) && (layer.GetGroup().GetName().Equals("_Markup")))
                    {
                        openMarkup[libraryPath + layer.GetLegendLabel() + ".LayerDefinition"] = layer.GetLegendLabel();
                    }
                }
            }
            return openMarkup;
        }
    }
}